home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / snmp / mib2c-data / mfd-persistence.m2i < prev    next >
Text File  |  2008-09-22  |  15KB  |  479 lines

  1. ########################################################################
  2. ## generic include for XXX. Do not use directly.
  3. ## $Id: mfd-persistence.m2i 15990 2007-03-23 09:19:51Z dts12 $
  4. ########################################################################
  5. @if $m2c_mark_boundary == 1@
  6. /** START code generated by $RCSfile$ $Revision: 15990 $ */
  7. @end@
  8. ########################################################################
  9. @if $m2c_processing_type eq 'h'@
  10. /* *********************************************************************
  11.  * Persistent declarations
  12.  */
  13. /*
  14.  * persistence
  15.  */
  16. #define LINE_TERM_CHAR '$'
  17.  
  18. void ${context}_container_init_persistence( netsnmp_container * container );
  19. int ${context}_container_should_save(${context}_rowreq_ctx * rowreq_ctx);
  20.  
  21. @end@ // m2c_processing_type eq 'h'
  22. ######################################################################
  23. ######################################################################
  24. ######################################################################
  25. @if $m2c_processing_type eq 'c'@
  26. /************************************************************
  27.  * the *_should_save routine is called to determine if a row
  28.  * should be stored persistently.
  29.  *
  30.  * Note that this is not a 'dirty' check (i.e. if a row has changed),
  31.  * but a check for volatile rows that should not be saved between
  32.  * restarts.
  33.  *
  34.  * return 1 if the row should be stored
  35.  * return 0 if the row should not be stored
  36.  */
  37. int
  38. ${context}_container_should_save(${context}_rowreq_ctx * rowreq_ctx)
  39. {
  40. @   foreach $node column@
  41. @      if "$node.syntax" eq "StorageType"@
  42. @         include m2c_setup_node.m2i@
  43.     if (SNMP_STORAGE_VOLATILE == $m2c_ctx_rh    )
  44.         return 0;
  45. @       end@
  46. @   end@
  47.     
  48.     return 1; /* save the row */
  49. }
  50.  
  51. @end@ // m2c_processing_type eq 'h'
  52. ######################################################################
  53. ######################################################################
  54. ######################################################################
  55. @if $m2c_processing_type eq 'i'@
  56. /***********************************************************************
  57.  *
  58.  * PERSISTENCE
  59.  *
  60.  ***********************************************************************/
  61.  
  62. static int _${context}_container_save_rows(int majorID, int minorID, void *serverarg, void *clientarg);
  63. static void _${context}_container_row_restore(const char *token, char *buf);
  64. static int _${context}_container_row_save(
  65.             ${context}_rowreq_ctx *rowreq_ctx,
  66.             void *type);
  67. static char * _${context}_container_col_restore(
  68.             ${context}_rowreq_ctx *rowreq_ctx,
  69.             u_int col, char* buf);
  70. static char * _${context}_container_col_save(
  71.             ${context}_rowreq_ctx *rowreq_ctx,
  72.             u_int col, char* buf);
  73.  
  74. static char row_token[] = "${context}";
  75.  
  76. /************************************************************
  77.  * *_init_persistence should be called from the main table
  78.  * init routine.
  79.  *
  80.  * If your table depends on rows in another table,
  81.  * you should register your callback after the other table,
  82.  * which should ensure the rows on which you depend are saved
  83.  * (and re-created) before the dependent rows.
  84.  */
  85. void
  86. ${context}_container_init_persistence( netsnmp_container * container )
  87. {
  88.     int rc;
  89.  
  90.     register_config_handler(NULL, row_token,
  91.                             _${context}_container_row_restore, NULL, NULL);
  92.     rc = snmp_register_callback( SNMP_CALLBACK_LIBRARY,
  93.                                      SNMP_CALLBACK_STORE_DATA,
  94.                                      _${context}_container_save_rows,
  95.                                      container);
  96.  
  97.     if( rc != SNMP_ERR_NOERROR )
  98.         snmp_log(LOG_ERR, "error registering for STORE_DATA callback "
  99.                  "in _${context}_container_init_persistence\n");
  100. }
  101.  
  102. static int
  103. _${context}_container_save_rows(int majorID, int minorID, void *serverarg, void *clientarg)
  104. {
  105.     char sep[] =
  106.         "##############################################################";
  107.     char buf[] =
  108.         "#\n"
  109.         "# $context persistent data\n"
  110.         "#";
  111.     char *type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
  112.                                        NETSNMP_DS_LIB_APPTYPE);
  113.  
  114.     read_config_store((char*)type, sep);
  115.     read_config_store((char*)type, buf);
  116.  
  117.     /*
  118.      * save all rows
  119.      */
  120.     CONTAINER_FOR_EACH((netsnmp_container*)clientarg,
  121.                        (netsnmp_container_obj_func*)_${context}_container_row_save,
  122.                        type);
  123.  
  124.     read_config_store((char*)type, sep);
  125.     read_config_store((char*)type, "\n");
  126.  
  127.     /*
  128.      * never fails 
  129.      */
  130.     return SNMPERR_SUCCESS;
  131. }
  132.  
  133.  
  134.  
  135. /************************************************************
  136.  * _${context}_container_row_save
  137.  */
  138. static int
  139. _${context}_container_row_save(
  140.             ${context}_rowreq_ctx *rowreq_ctx,
  141.             void *type)
  142. {
  143.     /*
  144.      * Allocate space for a line with all data for a row. An
  145.      * attempt is made to come up with a default maximum size, but
  146.      * there is no guarantee it will be enough. It probably will be,
  147.      * unless you are dealing with large values or you have external
  148.      * indexes.
  149.      *
  150.      * 1) allocate space for each column. Comment out columns you don't
  151.      * intend to save. You may also need to add room for any non-
  152.      * column data you want to store. Remeber, data will be stored in
  153.      * ASCII form, so you need to allow for that. Here are some
  154.      * general guidelines:
  155.      *
  156.      *   Object ID   :  12 * len [ASCII len of max int + 1 for .]
  157.      *   Octet String: (2 * len) + 2 [2 ASCII chars per byte + "0x"]
  158.      *   Integers    :  12 [ASCII len for smallest negative number]
  159.      *
  160.      * 2) You also need to allocate space for the row index. This will
  161.      * be stored as an OID, which means that Octet Strings need to
  162.      * be treated a little differently. Specifically, you will need
  163.      * (4 * len) + 4 [3 ASCII chars per byte + 1 for ., + 4 for len].
  164.      *
  165.      * 3) Also, remeber to add space for the identifier and seperator
  166.      * characters (for example, each column is prefixed by the
  167.      * column number and a semicolon. To allow for the maximum
  168.      * column values, 12 bytes [11 for oid + 1 for ':'] per
  169.      * column are added).
  170.      */
  171.         /** xxx: add storage for external index(s)! */
  172. #define MAX_ROW_SIZE (sizeof(row_token) + 1 +  \
  173. @   if $ext_index != 0@
  174.         ( 12 * 128 ) + /* external interfaces - max 128 subids */ \
  175. @   end@
  176. @   foreach $node nonindex@
  177. @      include m2c_setup_node.m2i@
  178. @    if ($node.settable == 1)@
  179. @      if "$node.type" eq "ASN_OBJECT_ID"@
  180.         ( ( 12 * sizeof(${m2c_ctx_rh}) ) + 3 ) + /* $node.type */ \
  181. @      elsif "$node.type" eq "ASN_OCTET_STR"@
  182.         ( ( 2 * sizeof(${m2c_ctx_rh}) ) + 3 ) + /* $node.type */ \
  183. @      else@
  184.         ( 12 ) + /* $node.type $node */ \
  185. @      end@
  186. @    end@
  187. @   end@
  188.         ( $table.uc_MAX_COL * 12 ) + /* column num prefix + : */ \
  189.     2 /* LINE_TERM_CHAR + \n */ )
  190.  
  191.     char buf[MAX_ROW_SIZE], *pos = buf, *max = &buf[MAX_ROW_SIZE-1];
  192.     char *tmp;
  193.     int i;
  194.  
  195.     if (${context}_container_should_save(rowreq_ctx) == 0) {
  196.         return SNMP_ERR_NOERROR;
  197.     }
  198.  
  199.     /*
  200.      * build the line
  201.      */
  202.     pos += sprintf(pos, "%s ", row_token);
  203.     pos = read_config_save_objid(pos, rowreq_ctx->oid_idx.oids,
  204.                                  rowreq_ctx->oid_idx.len);
  205.     if(NULL == pos) {
  206.         snmp_log(LOG_ERR,"error saving ${context} row "
  207.                  "to persistent file\n");
  208.         return SNMP_ERR_GENERR;
  209.     }
  210.     *pos++ = ' ';
  211.     if(pos > max) {
  212.         snmp_log(LOG_ERR,"error saving ${context} row "
  213.                  "to persistent file (too long)\n");
  214.         return SNMP_ERR_GENERR;
  215.     }
  216.  
  217.     /*
  218.      * add each column
  219.      */
  220.     for(i = $table.uc_MIN_COL; i <= $table.uc_MAX_COL; ++i ) {
  221.  
  222.         if ((0x1 << (i-1)) & ~$context.uc_SETTABLE_COLS)
  223.            continue;
  224.  
  225.         tmp = pos;
  226.         pos = _${context}_container_col_save(rowreq_ctx, i, pos);
  227.         if(NULL == pos)
  228.             pos = tmp;
  229.         else
  230.             *pos++ = ' ';        
  231.         if(pos > max) {
  232.             snmp_log(LOG_ERR,"error saving ${context} row "
  233.                      "to persistent file (too long)\n");
  234.             return SNMP_ERR_GENERR;
  235.         }
  236.     }
  237.  
  238.     /*
  239.      * if you have non-column data, add it here
  240.      */
  241.  
  242.  
  243.     /*
  244.      * store the line
  245.      */
  246.     pos += sprintf(pos, "%c", LINE_TERM_CHAR);
  247.     if(pos > max) {
  248.         snmp_log(LOG_ERR,"error saving ${context} row "
  249.                  "to persistent file (too long)\n");
  250.         return SNMP_ERR_GENERR;
  251.     }
  252.     read_config_store((char*)type, buf);
  253.  
  254.     DEBUGMSGTL(("internal:${context}:_${context}_container_row_save",
  255.                 "saving line '%s'\n", buf));
  256.     
  257.     return SNMP_ERR_NOERROR;
  258. }
  259.  
  260. static void
  261. _${context}_container_row_restore(const char *token, char *buf)
  262. {
  263.     ${context}_rowreq_ctx * rowreq_ctx;
  264.     netsnmp_index index;
  265.     oid tmp_oid[ MAX_${context}_IDX_LEN];
  266.     u_int col = 0, found = 0;
  267.  
  268.     
  269.     if (strncmp(token, row_token, sizeof(row_token)) != 0) {
  270.         snmp_log(LOG_ERR, "unknown token in _${context}_container_row_restore\n");
  271.         return;
  272.     }
  273.  
  274.     DEBUGMSGTL(("internal:${context}:_${context}_container_row_restore",
  275.                 "parsing line '%s'\n", buf));
  276.  
  277.     /*
  278.      * pull out index and create default row
  279.      */
  280.     index.oids = tmp_oid;
  281.     index.len = OID_LENGTH(tmp_oid);
  282.     buf = read_config_read_objid(buf, &index.oids,
  283.                                  &index.len);
  284.     if (NULL == buf) {
  285.         snmp_log(LOG_ERR, "error reading row index in "
  286.                  "_${context}_container_row_restore\n");
  287.         return;
  288.     }
  289.     rowreq_ctx = _mfd_${context}_rowreq_from_index( &index, NULL );
  290.     if (NULL == rowreq_ctx) {
  291.         snmp_log(LOG_ERR, "error creating row index in "
  292.                  "_${context}_container_row_restore\n");
  293.         return;
  294.     }
  295.     
  296.     /*
  297.      * loop through and get each column
  298.      */
  299.     buf = skip_white(buf);
  300.     while ( (NULL != buf) && isdigit(*buf) ) {
  301.         /*
  302.          * extract column, skip ':'
  303.          */
  304.         col = (u_int)strtol(buf, &buf, 10);
  305.         if (NULL == buf)
  306.             break;
  307.         if (*buf != ':') {
  308.             buf = NULL;
  309.             break;
  310.         }
  311.         ++buf; /* skip : */
  312.  
  313.         /*
  314.          * parse value
  315.          */
  316.         DEBUGMSGTL(("_${context}_container_row_restore",
  317.                     "parsing column %d\n", col));
  318.         buf = _${context}_container_col_restore( rowreq_ctx, col, buf );
  319.         ++found;
  320.     }
  321.     if (0 == found) {
  322.         snmp_log(LOG_ERR, "error parsing ${context} row; no columns found\n");
  323.         ${context}_release_rowreq_ctx( rowreq_ctx );
  324.         return;
  325.     }
  326.  
  327.     /*
  328.      * if you added any non-column data, this is where
  329.      * you should handle it.
  330.      */
  331.     
  332.     /*
  333.      * if the pointer is NULL and we didn't reach the
  334.      * end of the line, something went wrong. Log message,
  335.      * delete the row and bail.
  336.      */
  337.     if ((buf == NULL) || (*buf != LINE_TERM_CHAR)) {
  338.         snmp_log(LOG_ERR, "error parsing ${context} row around column %d\n",
  339.                  col);
  340.         ${context}_release_rowreq_ctx( rowreq_ctx );
  341.         return;
  342.     }
  343.  
  344.     DEBUGMSGTL(("internal:${context}:_${context}_container_row_restore",
  345.                 "inserting row\n"));
  346.  
  347.     /*
  348.      * copy oid index and insert row
  349.      */
  350.     rowreq_ctx->oid_idx.len = index.len;
  351.     memcpy(rowreq_ctx->oid_idx.oids, index.oids, index.len * sizeof(oid));
  352.  
  353.     CONTAINER_INSERT(${context}_if_ctx.container, rowreq_ctx);
  354. }
  355.  
  356. /************************************************************
  357.  * _${context}_container_col_save
  358.  */
  359. static char *
  360. _${context}_container_col_save(
  361.             ${context}_rowreq_ctx *rowreq_ctx,
  362.             u_int col, char* buf)
  363. {
  364.     if( ( NULL == rowreq_ctx ) || ( NULL == buf )) {
  365.         snmp_log(LOG_ERR, "bad parameter in "
  366.                  "_${context}_container_col_save\n");
  367.         return NULL;
  368.     }
  369.  
  370.     DEBUGMSGTL(("internal:${context}:_${context}_container_col_save",
  371.                 "processing column %d\n", col));
  372.  
  373.     /*
  374.      * prefix with column number, so we don't ever depend on
  375.      * order saved.
  376.      */
  377.     buf += sprintf(buf, "%u:", col);
  378.  
  379.     /*
  380.      * save data for the column
  381.      */
  382.     switch(col) {
  383.  
  384. @   foreach $node nonindex@
  385. @      include m2c_setup_node.m2i@
  386.         case COLUMN_$node.uc: /** $node.syntax = $node.type */
  387. @      if $m2c_node_needlength == 1@
  388. @         if "$node.type" eq "ASN_OBJECT_ID"@
  389.             buf = read_config_save_objid(buf, ${m2c_ctx_rh},
  390.                                          ${m2c_ctx_rhs} );
  391. @         else@ # "$node.type" eq "ASN_OCTET_STR"@
  392.             buf = read_config_save_octet_string(buf, ${m2c_ctx_rh},
  393.                                                 ${m2c_ctx_rhs} );
  394. @         end@
  395. @      elsif "$node.type" eq "ASN_INTEGER"@
  396.             buf += sprintf(buf,"%ld",${m2c_ctx_rh});
  397. @      else@
  398.             buf += sprintf(buf,"%lu",${m2c_ctx_rh});
  399. @      end@
  400.         break;
  401.     
  402. @   end@ # for each
  403.     default: /** We shouldn't get here */
  404.         snmp_log(LOG_ERR, "unknown column %d in "
  405.                  "_${context}_container_col_save\n", col);
  406.         return NULL;
  407.     }
  408.  
  409.     return buf;
  410. }
  411.  
  412. /************************************************************
  413.  * _${context}_container_col_restore
  414.  */
  415. static char *
  416. _${context}_container_col_restore(
  417.             ${context}_rowreq_ctx *rowreq_ctx,
  418.             u_int col, char* buf)
  419. {
  420.     size_t len;
  421.     if( ( NULL == rowreq_ctx ) || ( NULL == buf )) {
  422.         snmp_log(LOG_ERR, "bad parameter in "
  423.                  "_${context}_container_col_restore\n");
  424.         return NULL;
  425.     }
  426.  
  427.     DEBUGMSGTL(("verbose:${context}:_${context}_container_col_restore",
  428.                 "processing column %d\n", col));
  429.  
  430.     /*
  431.      * restore data for the column
  432.      */
  433.     switch(col) {
  434.  
  435. @   foreach $node nonindex@
  436. @      include m2c_setup_node.m2i@
  437.         case COLUMN_$node.uc: /** $node.syntax = $node.type */
  438. @      if $m2c_node_needlength == 1@
  439.             ${m2c_ctx_rhs} = sizeof(${m2c_ctx_rh});
  440.             buf = read_config_read_memory($node.type,buf,
  441.                                           (char*)&${m2c_ctx_rh},
  442.                                           (size_t*)&${m2c_ctx_rhs} );
  443. @         if "$node.type" eq "ASN_OBJECT_ID"@
  444.             ${m2c_ctx_rhs} /= sizeof(oid);
  445. @         end@
  446. @      else@
  447.             len = sizeof(${m2c_ctx_rh});
  448. @         if "$node.type" eq "ASN_OCTET_STR"@ # BITS
  449. @            eval $m2c_tmp = "ASN_INTEGER"@
  450. @         else@
  451. @            eval $m2c_tmp = $node.type@
  452. @         end@
  453.             buf = read_config_read_memory($m2c_tmp, buf,
  454.                                           (char*)&${m2c_ctx_rh},
  455.                                           &len);
  456. @      end@
  457. @      if $m2c_table_sparse == 1@
  458.             if (NULL != buf)
  459.                 rowreq_ctx->column_exists_flags |= COLUMN_$node.uc_FLAG;
  460. @      end@ # table sparse
  461.         break;
  462.     
  463. @   end@ # foreach col
  464.     default: /** We shouldn't get here */
  465.         snmp_log(LOG_ERR, "unknown column %d in "
  466.                  "_${context}_container_col_restore\n", col);
  467.         return NULL;
  468.     }
  469.  
  470.     return buf;
  471. }
  472.  
  473. ##
  474. @end@ // $m2c_processing_type eq 'i'
  475. ########################################################################
  476. @if $m2c_mark_boundary == 1@
  477. /** END code generated by $RCSfile$ $Revision: 15990 $ */
  478. @end@
  479.